﻿using Gac;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JD_spider
{
    public partial class spider : Form
    {
        public spider()
        {
            InitializeComponent();
        }

        DownLoadFile down = new DownLoadFile();

        //商品ID
        public static String GoodID;

        //商品名称
        public static String GoodName;

        //商品图片
        public static ArrayList GoodImages = new ArrayList();

        private void btnCheck_Click(object sender, EventArgs e)
        {
            GoodImages.Clear();
            flpImage.Controls.Clear();

            GoodID = inputID.Text.ToString();
            if(string.IsNullOrWhiteSpace(GoodID))
            {
                MessageBox.Show("请输入商品ID");
                return;
            }

            //定义一个为空的页面标题
            String IsEmptyTitle = "京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物！";

            String url = "https://item.jd.com/" + GoodID + ".html";
            WebRequest request = WebRequest.Create(url);

            WebResponse response = request.GetResponse();

            //获取页面编码 防止中文乱码
            String contentType = response.ContentType;
            Regex regex = new Regex("charset\\s*=\\s*(?<charset>[\\w-]+)", RegexOptions.IgnoreCase);
            String charset = regex.Match(contentType).Groups["charset"].Value;

            Stream stream = response.GetResponseStream();

            using (StreamReader reader = new StreamReader(stream, Encoding.GetEncoding(charset)))
            {
                //获取整个页面信息 用于分析
                String result = reader.ReadToEnd();
                
                //获取页面标题 用于判断JD是否跳转到了首页
                Regex reg = new Regex("<title>(.*)</title>");

                Match match = reg.Match(result);

                //获取标题内容
                String matchString = match.ToString();
                matchString = matchString.Replace("<title>", string.Empty);
                matchString = matchString.Replace("</title>", string.Empty);

                //与上面为空的标题进行对比
                int compare = String.Compare(matchString.Trim(), IsEmptyTitle.Trim());
                if (compare == 0)
                {
                    txtResult.AppendText(DateTime.Now + "--" + "未找到相关商品" + Environment.NewLine);
                    return;
                }
                else
                {
                    txtResult.AppendText(DateTime.Now + "--" + "成功获取商品：" + matchString + Environment.NewLine);

                    //分析图片
                    Regex imgLiRegex = new Regex("<li  class='img-hover'>(.*)<div class=\"preview-info\">", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    Match imgLiMatch = imgLiRegex.Match(result);

                    String imgLiMatchString = imgLiMatch.ToString();

                    //匹配出图片地址
                    Regex imgRegex = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<src>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>",  RegexOptions.IgnoreCase);
                    MatchCollection imgMatch = imgRegex.Matches(imgLiMatchString);

                    //获取商品名称
                    Regex altRegex = new Regex(@"<img\b[^<>]*?\balt[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<alt>[^""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase);
                    GoodName = altRegex.Match(imgLiMatchString).Groups["alt"].Value;
                    GoodName = GoodName.Replace('/', ' ');
                    GoodName = GoodName.Replace('\\', ' ');

                    foreach (Match m in imgMatch)
                    {
                        String imageSrc = m.Groups["src"].Value;
                        if (!string.IsNullOrWhiteSpace(imageSrc))
                        {
                            GoodImages.Add(imageSrc);

                            //浏览图片
                            PictureBox picture = new PictureBox();

                            WebClient client = new WebClient();
                            Image image = Image.FromStream(client.OpenRead("https:" + imageSrc));
                            picture.Image = image;
                            flpImage.Controls.Add(picture);
                        }
                    }
                }
            }

        }

        private void btnSpider_Click(object sender, EventArgs e)
        {
            String name = string.Empty;
            if (IsGoodName.Checked)
            {
                name = GoodName;
            }
            else
            {
                name = GoodID;
            }

            for(int i = 0; i < GoodImages.Count; i++)
            {
                String smallUrl = GoodImages[i].ToString();
                String bigURL = smallUrl.Replace("/n5/", "/n1/");
                bigURL = bigURL.Replace("s54x54", "s450x450");

                String bigImageUrl = "https:"+ bigURL;
                String smallImageUrl = "https:"+ smallUrl;

                String ext = smallUrl.Substring(smallUrl.LastIndexOf(".") + 1, (smallUrl.Length - smallUrl.LastIndexOf(".") - 1));

                String bigImageName = name + "-450x450-" + i + "." + ext;
                String smallImageName = name + "-54x54-" + i + "." + ext;

                String SaveFile = fbdImageFile.SelectedPath;

                if (IsGoodNameFile.Checked)
                {
                    SaveFile = SaveFile + '\\' + GoodName;
                }

                if (IsThumbnail.Checked)
                {
                    down.AddDown(smallImageUrl, SaveFile, i, smallImageName);
                }
                down.AddDown(bigImageUrl, SaveFile, i, bigImageName);
            }

            down.StartDown();
        }

        private void DownHander(DownMsg msg)
        {
            switch (msg.Tag)
            {
                case DownStatus.Start:
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        txtResult.AppendText(DateTime.Now + "--" + "开始下载" + Environment.NewLine);
                    });
                    break;
                case DownStatus.GetLength:
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        txtResult.AppendText(DateTime.Now + "--" + "连接成功" +  Environment.NewLine);
                    });
                    break;
                case DownStatus.End:
                case DownStatus.DownLoad:
                    this.Invoke(new MethodInvoker(() =>
                    {
                        this.Invoke((MethodInvoker)delegate ()
                        {
                            if (msg.Tag == DownStatus.DownLoad)
                            {
                                txtResult.AppendText(DateTime.Now + "--" + "下载中" + Environment.NewLine);
                            }
                            else
                            {
                                txtResult.AppendText(DateTime.Now + "--" + "下载完成" + Environment.NewLine);
                            }
                            Application.DoEvents();
                        });
                    }));
                    break;
                case DownStatus.Error:
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        txtResult.AppendText(DateTime.Now + "--" + "失败:" + msg.ErrMessage + Environment.NewLine);
                        Application.DoEvents();
                    });
                    break;
            }
        }

        private void spider_Load(object sender, EventArgs e)
        {
            down.ThreadNum = 3;//线程数，不设置默认为3
            down.doSendMsg += DownHander;//下载过程处理事件

            //默认保存图片的位置
            fbdImageFile.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            labelSaveImageFile.Text = fbdImageFile.SelectedPath;
        }

        private void btnselectFolder_Click(object sender, EventArgs e)
        {
            fbdImageFile.Description = "请选择保存图片的位置";
            fbdImageFile.ShowDialog();
            labelSaveImageFile.Text = fbdImageFile.SelectedPath;
        }
    }
}
